package com.study.sfd.person.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.study.common.entity.DoctorEntity;
import com.study.common.entity.PatientEntity;
import com.study.common.utils.Result;
import com.study.sfd.person.dao.*;
import com.study.sfd.person.entity.*;
import com.study.sfd.person.enums.Role;
import com.study.sfd.person.enums.VerifyStatus;
import com.study.sfd.person.service.AccountService;
import com.study.sfd.person.utils.JwtUtil;
import com.study.sfd.person.utils.Utils;
import com.study.sfd.person.vo.AccountVo;
import com.study.sfd.person.vo.RegisterVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

import static com.study.sfd.person.utils.PasswordUtils.hashPassword;
import static com.study.sfd.person.utils.PasswordUtils.verifyPassword;


@Service("accountService")
public class AccountServiceImpl extends ServiceImpl<AccountDao, AccountEntity> implements AccountService
{
    @Autowired
    DruggistDao druggistDao;

    @Autowired
    DoctorDao doctorDao;

    @Autowired
    PatientDao patientDao;

    @Autowired
    DruggistDoctorRelationDao druggistDoctorRelationDao;

    @Autowired
    DoctorPatientRelationDao doctorPatientRelationDao;

    @Transactional
    @Override
    public void register(RegisterVo registerVo)
    {
        AccountEntity account = new AccountEntity();
        // roleId, phone, password
        BeanUtils.copyProperties(registerVo, account);
        account.setPassword(hashPassword(account.getPassword()));
        save(account);
        Integer accountId = account.getId();

        if (account.getRoleId() == Role.Druggist.getId()) {
            DruggistEntity druggist = new DruggistEntity();
            druggist.setAccountId(accountId);
            // todo 审核药商
            druggist.setVerifyStatus(VerifyStatus.PASSED.getValue());
            druggist.setMyInviteCode(Utils.genInviteCode());
            druggistDao.insert(druggist);
        } else if (account.getRoleId() == Role.Doctor.getId()) {
            DoctorEntity doctor = new DoctorEntity();
            doctor.setAccountId(accountId);
            doctor.setVerifyStatus(VerifyStatus.NOT_COMMIT.getValue());
            doctorDao.insert(doctor);

            DruggistEntity druggist = druggistDao.selectOne(
                    new LambdaQueryWrapper<DruggistEntity>()
                            .eq(DruggistEntity::getMyInviteCode, registerVo.getInviterCode())
            );
            DruggistDoctorRelationEntity druggistDoctorRelation = new DruggistDoctorRelationEntity();
            druggistDoctorRelation.setDoctorId(doctor.getId());
            druggistDoctorRelation.setDruggistId(druggist.getId());
            druggistDoctorRelationDao.insert(druggistDoctorRelation);
        } else {
            PatientEntity patient = new PatientEntity();
            patient.setAccountId(accountId);
            patient.setName(registerVo.getName());
            patient.setAge(registerVo.getAge());
            patient.setSex(registerVo.getSex());
            patientDao.insert(patient);

            DoctorEntity doctor  = doctorDao.selectOne(
                    new LambdaQueryWrapper<DoctorEntity>()
                            .eq(DoctorEntity::getMyInviteCode, registerVo.getInviterCode())
            );
            DoctorPatientRelationEntity doctorPatientRelation = new DoctorPatientRelationEntity();
            doctorPatientRelation.setPatientId(patient.getId());
            doctorPatientRelation.setDoctorId(doctor.getId());
            doctorPatientRelationDao.insert(doctorPatientRelation);
        }
    }

    @Override
    public Result<?> login(String phone, String password)
    {
        AccountEntity accountByPhone = lambdaQuery()
                .eq(AccountEntity::getPhone, phone)
                .one();
        if (accountByPhone == null) {
            return Result.error("此手机号没有被注册");
        }
        if (!verifyPassword(password, accountByPhone.getPassword())) {
            return Result.error("密码错误");
        }
        AccountVo accountVo = new AccountVo();
        BeanUtils.copyProperties(accountByPhone, accountVo);

        Map<String, Object> claims = new HashMap<>();

        Integer accountId = accountByPhone.getId();
        if (accountByPhone.getRoleId() == Role.Druggist.getId()) {
            DruggistEntity druggist = druggistDao.selectOne(
                    new LambdaQueryWrapper<DruggistEntity>()
                            .eq(DruggistEntity::getAccountId, accountId)
            );
            accountVo.setDruggist(druggist);
            claims.put("druggistId", druggist.getId());
        } else if (accountByPhone.getRoleId() == Role.Doctor.getId()) {
            DoctorEntity doctor = doctorDao.selectOne(
                    new LambdaQueryWrapper<DoctorEntity>()
                            .eq(DoctorEntity::getAccountId, accountId)
            );
            accountVo.setDoctor(doctor);
            claims.put("doctorId", doctor.getId());
        } else if (accountByPhone.getRoleId() == Role.Patient.getId()) {
            PatientEntity patient = patientDao.selectOne(
                    new LambdaQueryWrapper<PatientEntity>()
                            .eq(PatientEntity::getAccountId, accountId)
            );
            accountVo.setPatient(patient);
            claims.put("patientId", patient.getId());
        }
        claims.put("accountId", accountId);
        String token = JwtUtil.genToken(claims);

        accountVo.setToken(token);

        return Result.success(accountVo);
    }

}